package com.wnxy.sddfp.trade.service.impl;
import java.math.BigDecimal;
import java.util.Date;
import java.util.UUID;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wnxy.sddfp.client.system.UserApi;
import com.wnxy.sddfp.trade.entity.BorrowRecord;
import com.wnxy.sddfp.trade.mapper.BorrowRecordMapper;
import com.wnxy.sddfp.trade.service.IBorrowRecordService;
import com.woniuxy.bank.api.access.TradeLogApi;
import com.woniuxy.sddfp.common.exception.Assert;
import com.woniuxy.sddfp.common.exception.BusinessException;
import com.woniuxy.sddfp.common.model.BaseResult;
import com.woniuxy.sddfp.common.model.dto.trade.BorrowRecordDTO;
import com.woniuxy.sddfp.common.model.vo.trade.BorrowSyncRecordVo;
import com.woniuxy.sddfp.common.model.vo.user.UserInfoVo;
import com.woniuxy.sddfp.common.result.Result;
import com.woniuxy.sddfp.common.result.enums.impl.ResultCode;
import com.woniuxy.sddfp.common.utils.TokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;


@Slf4j
@Service
public class BorrowRecordServiceImpl extends ServiceImpl<BorrowRecordMapper, BorrowRecord> implements IBorrowRecordService {

    @Autowired
    private UserApi userApi;

    @Autowired
    private TradeLogApi tradeLogApi;


    @Override
    public void addBorrowRecord(BorrowRecordDTO borrowRecordDTO) {

        // 创建要保存的对象
        BorrowRecord borrowRecord = new BorrowRecord();

        // 获取登录用户id
        String userId = TokenUtils.getTokenUserId();
        long uid = Long.parseLong(userId);
        borrowRecord.setUserId(uid);

        // openfeign远程调用：访问系统管理服务
        Result<UserInfoVo> userInfoVoResult = userApi.findById(uid);
        UserInfoVo userInfoVo = userInfoVoResult.getData();

        // 设置借款名称，如：XX先生的第1次借款
        borrowRecord.setName(this.covertName(userInfoVo));
        borrowRecord.setUserCode(userInfoVo.getUserCode());
        borrowRecord.setPeriod(borrowRecordDTO.getPeriod());
        borrowRecord.setAmount(borrowRecordDTO.getAmount());

        // 设置借款编号
        borrowRecord.setBorrowRecordNo("BO_" +
                UUID.randomUUID().toString().replace("-","").substring(0,10));
        borrowRecord.setDescription("无");

        // 各种利率 （先写死，应该放到配置文件中）
        borrowRecord.setInvestRate(new BigDecimal("10"));
        borrowRecord.setBorrowerRate(new BigDecimal("10"));
        borrowRecord.setCommissionRate(new BigDecimal("10"));
        borrowRecord.setRepaymentWay("DEBX");

        borrowRecord.setBorrowStatus("0");
        borrowRecord.setCreateDate(new Date());
        borrowRecord.setModifyDate(new Date());
        borrowRecord.setStatus(false);
        // 保存借款记录
        save(borrowRecord);

        log.info("保存借款记录成功：{}",borrowRecord);
    }


    /**
     * 处理借款名称 (如：许敏女士第1次借款)
     * @param userInfoVo
     * @return
     */
    private String covertName(UserInfoVo userInfoVo) {
        // 根据用户编码（唯一）查询用户借款次数
        long count = this.count(
                Wrappers.lambdaQuery(BorrowRecord.class)
                        .eq(BorrowRecord::getUserCode, userInfoVo.getUserCode()));
        StringBuffer sb = new StringBuffer();
        sb.append(userInfoVo.getUserName());
        sb.append(getGender(userInfoVo.getIdentityCode()));
        sb.append("第" + (count + 1) );
        sb.append("次借款");
        return sb.toString();
    }

    /**
     * 根据身份证号码返回性别：先生、女士
     */
    private String getGender(String identityCode) {
        // 判断身份证号码必须是18位
        Assert.error(
                identityCode==null || identityCode.length()!=18,
                ResultCode.DATA_IS_WRONG);
        // 截取
        Integer n = Integer.parseInt(identityCode.substring(16,17));
        return n % 2 == 0 ? "女士" : "先生";
    }


    /**
     * 1、生成流水号并更新借款记录表： borrow_record 表的 req_code字段
     *
     *       注意： 如何借款记录中以及由流水号就不更新了！
     *
     * 2、远程调用，同步借款记录：  BorrowSyncRecordVo
     *
     * 3、根据远程调用返回结果， 修改借款记录的数据同步状态；
     *  BorrowRecord表的status=1、borrow_status为SYNC 已同步
     */
    @Override
    public String verifyStatus(Integer approveStatus, Long borrowRecordId) {
        //1. 根据借款记录id查询
        BorrowRecord borrowRecord = this.getById(borrowRecordId);

        //2. 更新流水号：如果borrow_record表的REQ_CODE流水号已经生成过，就不需要重新重新
        if (StringUtils.isEmpty(borrowRecord.getReqCode())) {
            // 生成流水号
            String reqCode = "REQ_" + UUID.randomUUID().toString().substring(0,10);
            // 更新借款记录表流水号字段
            this.update(Wrappers.lambdaUpdate(BorrowRecord.class)
                    .set(BorrowRecord::getReqCode,reqCode)
                    .eq(BorrowRecord::getId,borrowRecordId)
            );
            // 设置流水号到borrowRecord对象中，后面远程调用需要这个参数
            borrowRecord.setReqCode(reqCode);
        }

        //2.1、根据接口规范，准备远程调用参数
        //对象拷贝：borrowRecord --> BorrowSyncRecordVo
        BorrowSyncRecordVo borrowSyncRecordVo =
                BeanUtil.copyProperties(borrowRecord, BorrowSyncRecordVo.class);

        //3. 远程调用（模拟...）
        Result<BaseResult> result = tradeLogApi.syncBorrowRecord(borrowSyncRecordVo);
        //3、根据远程调用结果，返回msg=成功，修改BorrowRecord表的status=1、borrow_status为SYNC
        if (result.getCode() == ResultCode.SUCCESS.getCode()) {
            // 修改状态
            this.update(Wrappers.lambdaUpdate(BorrowRecord.class)
                    .set(BorrowRecord::getStatus,approveStatus)
                    .set(BorrowRecord::getBorrowStatus,"SYNC")
                    .eq(BorrowRecord::getId,borrowRecordId)
            );
            return "success";
        }
        throw new BusinessException(ResultCode.FAILED);
    }

}
